package cn.cdiothree.service.impl;

import cn.cdiothree.dao.AuthMapper;
import cn.cdiothree.dao.UserMapper;
import cn.cdiothree.domain.auth.Role;
import cn.cdiothree.domain.auth.User;
import cn.cdiothree.domain.auth.UserDetail;
import cn.cdiothree.enums.MessageEnum;
import cn.cdiothree.exception.UserException;
import cn.cdiothree.service.SecurityService;
import cn.cdiothree.util.JwtUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * 用户注册服务类
 * @author cumthing
 */
@Service
@Slf4j
public class RegisterServiceImpl implements SecurityService {

    private HttpSession httpSession;
    private final AuthenticationManager authenticationManager;
    private final UserDetailsService userDetailsService;
    private final JwtUtils jwtTokenUtil;
    private final AuthMapper authMapper;
    @Autowired
    private AliSendSmsCodeImpl sendSmsCode;

    @Autowired
    private UserMapper userMapper;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    public RegisterServiceImpl(AuthenticationManager authenticationManager, UserDetailsService userDetailsService, JwtUtils jwtTokenUtil, AuthMapper authMapper, AliSendSmsCodeImpl sendSmsCode) {
        this.authenticationManager = authenticationManager;
        this.userDetailsService = userDetailsService;
        this.jwtTokenUtil = jwtTokenUtil;
        this.authMapper = authMapper;
        this.sendSmsCode = sendSmsCode;
    }

    /**
     * 获取短信验证码
     * @param request
     * @param response
     */
    @Override
    public void verify(HttpServletRequest request, HttpServletResponse response){
        String telephone = request.getParameter("telephone");
        String verifyNum = RandomStringUtils.randomNumeric(6);
        httpSession = request.getSession();
        httpSession.setAttribute(telephone,verifyNum);
        sendSmsCode.send(telephone,verifyNum);
    }

    /**
     * 修改密码
     * @param request
     * @param response
     * @param token
     */
    @Override
    public void changeSecret(HttpServletRequest request, HttpServletResponse response,String token){

        String password = request.getParameter("newpw");


        token = token.substring(tokenHead.length());
        String userName = jwtTokenUtil.getUsernameFromToken(token);
        log.info("用户{}修改密码",userName);
//        if (!password.equals(rePassword)){
//            throw new RuntimeException("两次输入的密码不一致");
//        }

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name",userName);
        User user1 = userMapper.selectOne(wrapper);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user1.setPassword(encoder.encode(password));
        userMapper.updateById(user1);
    }

    /**
     * 忘记密码
     * @param request
     * @param response
     */
    @Override
    public void forgetSecret(HttpServletRequest request, HttpServletResponse response){
        String varPhone = request.getParameter("telephone");
        String verCode = request.getParameter("ver");
        String sessionCode = (String) httpSession.getAttribute(varPhone);
        if (!verCode.equals(sessionCode)){
            throw new RuntimeException("验证码不正确");
        }
        String password = request.getParameter("newpw");
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("telephone",varPhone);
        User user1 = userMapper.selectOne(wrapper);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user1.setPassword(encoder.encode(password));
        log.info("用户{}忘记密码修改密码成功",user1.getName());
        userMapper.updateById(user1);
    }

    /**
     * 注册
     * @param request
     * @param response
     */
    @Override
    public void register(HttpServletRequest request, HttpServletResponse response){
        String verifyCode = request.getParameter("verify");
        String telephone = request.getParameter("telephone");
        String sessionVerify = (String) httpSession.getAttribute(telephone);
        if (!verifyCode.equals(sessionVerify)){
            throw new RuntimeException("验证码不正确");
        }
        String password = request.getParameter("password");
        String username = request.getParameter("username");
        if(authMapper.findByUsername(username)!=null) {
            throw new UserException(MessageEnum.USER_EXIST);
        }
        log.info("新增用户{}，绑定手机号为{}",username,telephone);
        User user = new User();
//        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        user.setPassword(password);
        user.setTelephone(telephone);
        user.setName(username);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        UserDetail userDetail = new UserDetail(user.getName(), encoder.encode(user.getPassword()),user.getTelephone(),Role.builder().id(1L).build());
        userDetail.setLastPasswordResetDate(new Date());
        authMapper.insert(userDetail);

        long roleId = userDetail.getRole().getId();
        Role role = authMapper.findRoleById(roleId);
        userDetail.setRole(role);
        authMapper.insertRole(userDetail.getId(), roleId);

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name",userDetail.getUsername());
        User user1 = new User();
        user1.setTelephone(telephone);
        userMapper.update(user1,wrapper);
    }



}
